iT邦幫忙

0

Day 28|API 文件整理與測試

c#
  • 分享至 

  • xImage
  •  

今日學習目標

  • 確認 OpenAPI 文件功能正常
  • 為 API 加上功能說明與回應狀態碼
  • 建立 API 使用說明文件
  • 測試登入、CRUD、錯誤處理及資料隔離

認識 API 文件、OpenAPI 與 Swagger UI

API 文件就像程式提供給其他開發者的使用說明書。
ASP.NET Core 10 可以使用 OpenAPI 產生 API 規格文件,再透過 Swagger UI 顯示成容易閱讀的互動頁面。

為 TasksController 加上 API 說明

**打開檔案:**TaskFlow3.Api → Controllers → TasksController.cs
在 GET 全部任務的方法上方加入
找到:

[HttpGet]
public async Task<ActionResult<List<TaskDto>>> GetTasks(

修改為:

[HttpGet]
[EndpointSummary("取得目前使用者的任務")]
[EndpointDescription(
    "取得登入者自己的任務,可依完成狀態、關鍵字及排序條件查詢。"
)]
[ProducesResponseType(
    typeof(List<TaskDto>),
    StatusCodes.Status200OK
)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<List<TaskDto>>> GetTasks(

在 GET 單一任務的方法上方加入
找到 GetTask(int id),讓它的開頭變成:

[HttpGet("{id:int}")]
[EndpointSummary("取得指定任務")]
[EndpointDescription(
    "根據任務 ID 取得登入者自己的任務,不會回傳其他使用者的任務。"
)]
[ProducesResponseType(
    typeof(TaskDto),
    StatusCodes.Status200OK
)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<TaskDto>> GetTask(int id)

在 POST 新增任務的方法上方加入
找到 CreateTask():

[HttpPost]
[EndpointSummary("新增任務")]
[EndpointDescription(
    "為目前登入使用者建立一筆新任務,任務名稱必須介於 2 到 100 個字元。"
)]
[ProducesResponseType(
    typeof(TaskDto),
    StatusCodes.Status201Created
)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<TaskDto>> CreateTask(
    [FromBody] CreateTaskDto input)

在 PUT 修改任務的方法上方加入
找到 UpdateTask():

[HttpPut("{id:int}")]
[EndpointSummary("修改任務")]
[EndpointDescription(
    "修改登入者自己的任務名稱與完成狀態。"
)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> UpdateTask(
    int id,
    [FromBody] UpdateTaskDto input)

在 DELETE 刪除任務的方法上方加入
找到 DeleteTask():

[HttpDelete("{id:int}")]
[EndpointSummary("刪除任務")]
[EndpointDescription(
    "刪除登入者自己的指定任務,不能刪除其他使用者的任務。"
)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> DeleteTask(int id)

建立正式的 API 說明文件

建立新檔案
在 VS Code 左側找到最外層:TaskFlow3
按右鍵選擇「新增檔案」,命名為:API_DOCUMENTATION.md
文件內容

# TaskFlow API 文件
## 1. 專案介紹
TaskFlow 是使用 C#、ASP.NET Core 及 SQLite
開發的任務管理 Web API。
主要功能:
- 註冊與登入
- 新增、查詢、修改與刪除任務
- 依完成狀態篩選任務
- 依任務名稱搜尋
- 依任務 ID 排序
- 限制使用者只能存取自己的任務
## 2. 使用技術
- C#
- .NET 10
- ASP.NET Core Web API
- Entity Framework Core
- SQLite
- ASP.NET Core Identity
- OpenAPI / Swagger UI
- xUnit
- Git
## 3. 本機 API 網址
實際連接埠依 dotnet run 顯示的網址為準。
範例:
http://localhost:5028
Swagger UI:
http://localhost:5028/swagger
OpenAPI JSON:
http://localhost:5028/openapi/v1.json
## 4. 任務 API
| 方法 | 路徑 | 功能 |
|---|---|---|
| GET | /api/tasks | 查詢自己的任務 |
| GET | /api/tasks/{id} | 查詢指定任務 |
| POST | /api/tasks | 新增任務 |
| PUT | /api/tasks/{id} | 修改任務 |
| DELETE | /api/tasks/{id} | 刪除任務 |
上述任務 API 都要求使用者先登入。
## 5. 登入 API
由 ASP.NET Core Identity 提供:
POST /auth/register
POST /auth/login?useCookies=true
登入成功後,可使用同一個 Cookie Session
存取受保護的任務 API。
## 6. 新增任務範例
POST /api/tasks
Request Body:
json
{
  "title": "完成 C# 作業"
}
成功後預期回傳 HTTP 201。
Response Body 範例:
json
{
  "id": 1,
  "title": "完成 C# 作業",
  "isCompleted": false
}
## 7. 修改任務範例
PUT /api/tasks/1
Request Body:
json
{
  "title": "完成 ASP.NET Core 作業",
  "isCompleted": true
}
成功後預期回傳 HTTP 204。
## 8. 查詢參數
GET /api/tasks?completed=false
只查詢未完成任務。
GET /api/tasks?keyword=C%23
搜尋名稱包含 C# 的任務。
GET /api/tasks?sort=desc
依任務 ID 由大到小排序。
參數可以組合使用。
## 9. 常見 HTTP 狀態碼
| 狀態碼 | 意義 |
|---|---|
| 200 | 查詢成功 |
| 201 | 新增成功 |
| 204 | 修改或刪除成功 |
| 400 | 請求資料不符合規則 |
| 401 | 尚未通過身分驗證 |
| 404 | 找不到屬於登入者的指定任務 |
| 500 | 伺服器發生未預期錯誤 |
## 10. 資料安全
每筆新任務都有 OwnerIdentityId。
查詢、修改與刪除時,後端會根據已驗證的
登入者 ID 限制可存取的任務。
不同使用者的私人任務不得互相存取。
## 11. 執行專案
在 TaskFlow3.Api 目錄執行:
powershell
dotnet run
在 TaskFlow3 根目錄執行測試:
powershell
dotnet test .\TaskFlow3.Tests\TaskFlow3.Tests.csproj
## 12. 測試結果
測試日期:尚未填寫
測試環境:Windows / .NET 10
新增任務:待測試
查詢任務:待測試
修改任務:待測試
刪除任務:待測試
登入驗證:待測試
使用者資料隔離:待測試
測試完成後再填入實際結果。

TaskFlow 的 API 功能

https://ithelp.ithome.com.tw/upload/images/20261025/20184430DfGKrtRs2p.png

測試 API

啟動 API
在終端機 1:

cd TaskFlow3.Api
dotnet run

設定測試網址
在終端機 2:$base = "http://localhost:5130"
執行:Invoke-RestMethod -Uri "$base/test" -Method Get
登入測試帳號

$login = @{
    email = "student@example.com"
    password = "DemoOnly_2026!"
} | ConvertTo-Json

再執行:

Invoke-RestMethod `
    -Uri "$base/auth/login?useCookies=true" `
    -Method Post `
    -ContentType "application/json" `
    -Body $login `
    -SessionVariable aliceSession

新增任務(POST)
在同一個終端機 2 輸入:

$body = @{
    title = "Day 28 API 測試"
} | ConvertTo-Json

$created = Invoke-RestMethod `
    -Uri "$base/api/tasks" `
    -Method Post `
    -ContentType "application/json" `
    -Body $body `
    -WebSession $aliceSession

$created

https://ithelp.ithome.com.tw/upload/images/20261025/20184430BT0gTK0qso.png
查詢任務(GET)
輸入:

Invoke-RestMethod `
    -Uri "$base/api/tasks" `
    -Method Get `
    -WebSession $aliceSession

測試查詢單一任務:

Invoke-RestMethod `
    -Uri "$base/api/tasks/$($created.id)" `
    -Method Get `
    -WebSession $aliceSession

https://ithelp.ithome.com.tw/upload/images/20261025/20184430gIt9Zxr2Hl.png
修改任務(PUT)
先建立修改資料:

$updateBody = @{
    title = "Day 28 測試已完成"
    isCompleted = $true
} | ConvertTo-Json

接著執行:

Invoke-RestMethod `
    -Uri "$base/api/tasks/$($created.id)" `
    -Method Put `
    -ContentType "application/json" `
    -Body $updateBody `
    -WebSession $aliceSession

再使用 GET 確認:

Invoke-RestMethod `
    -Uri "$base/api/tasks/$($created.id)" `
    -WebSession $aliceSession

測試搜尋與篩選
查詢已完成的任務:

Invoke-RestMethod `
    -Uri "$base/api/tasks?completed=true" `
    -WebSession $aliceSession

查詢包含 Day 的任務:

Invoke-RestMethod `
    -Uri "$base/api/tasks?keyword=Day" `
    -WebSession $aliceSession

依任務 ID 降冪排序:

Invoke-RestMethod `
    -Uri "$base/api/tasks?sort=desc" `
    -WebSession $aliceSession

刪除任務(DELETE)
最後刪除剛剛新增的測試任務:

Invoke-RestMethod `
    -Uri "$base/api/tasks/$($created.id)" `
    -Method Delete `
    -WebSession $aliceSession

測試錯誤處理

沒有登入就查詢任務

try {
    Invoke-RestMethod `
        -Uri "$base/api/tasks" `
        -Method Get `
        -ErrorAction Stop
}
catch {
    Write-Host "HTTP 狀態碼:" ([int]$_.Exception.Response.StatusCode)
}

https://ithelp.ithome.com.tw/upload/images/20261025/20184430H4apn3iW4J.png
任務名稱太短
輸入:

$invalidBody = @{
    title = "A"
} | ConvertTo-Json

try {
    Invoke-RestMethod `
        -Uri "$base/api/tasks" `
        -Method Post `
        -ContentType "application/json" `
        -Body $invalidBody `
        -WebSession $aliceSession `
        -ErrorAction Stop
}
catch {
    Write-Host "HTTP 狀態碼:" ([int]$_.Exception.Response.StatusCode)
}

https://ithelp.ithome.com.tw/upload/images/20261025/20184430PVb9y6MOjH.png
使用不存在的任務 ID

try {
    Invoke-RestMethod `
        -Uri "$base/api/tasks/99999999" `
        -Method Get `
        -WebSession $aliceSession `
        -ErrorAction Stop
}
catch {
    Write-Host "HTTP 狀態碼:" ([int]$_.Exception.Response.StatusCode)
}

https://ithelp.ithome.com.tw/upload/images/20261025/20184430zr9Lahz6nV.png


*提醒邦友,使用第三方服務/API 時,請務必評估資安風險與隱私保護
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言